<template>
  <div>
    <el-row :gutter="20">
      <el-col :span="12">
        <el-card shadow="hover">
          <template #header>
            <div class="clearfix">
              <span>我的信息</span>
            </div>
          </template>
          <div class="info">
            <div class="info-image" @click="showDialog">
              <img :src="avatarImg" />
              <span class="info-edit">
                <i class="el-icon-lx-camerafill"></i>
              </span>
            </div>
            <div class="info-name">{{ userInfo.nickname }}</div>
            <div v-if="userInfo.description" class="info-desc">
              {{ userInfo.description }}
            </div>
            <div v-else class="info-desc">
              你还没有添加简介，来秀出你的个性吧！
            </div>
          </div>
        </el-card>
      </el-col>

      <el-col :span="12">
        <el-card shadow="hover">
          <template #header>
            <div class="clearfix d_f j_s a_c">
              <span>{{ isEdit ? "编辑" : "查看" }}资料</span>
              <el-button-group>
                <el-button
                  v-if="isEdit"
                  size="mini"
                  :loading="editBtnLoading"
                  type="primary"
                  @click="onSubmit"
                >
                  保存
                </el-button>
                <el-button size="mini" @click="toggleEditStatus">
                  {{ isEdit ? "取消" : "编辑" }}
                </el-button>
              </el-button-group>
            </div>
          </template>
          <el-form
            ref="formRef"
            :model="form"
            :rules="rules"
            label-width="90px"
          >
            <el-form-item label="登录名：">
              {{ userInfo.username }}
            </el-form-item>

            <el-form-item label="角色：">
              {{ userInfo.roleName }}
            </el-form-item>

            <el-form-item label="昵称：" prop="nickname">
              <el-input v-if="isEdit" v-model="form.nickname"></el-input>
              <span v-else :class="{ color_gray: !form.nickname }">
                {{ form.nickname || "未填写" }}
              </span>
            </el-form-item>

            <el-form-item
              label="姓名："
              prop="truename"
              :class="{
                bg_yellow: bgYellowControl.truename,
              }"
            >
              <el-input v-if="isEdit" v-model="form.truename"></el-input>
              <span v-else :class="{ color_gray: !form.truename }">
                {{ form.truename || "未填写" }}
              </span>
            </el-form-item>

            <el-form-item label="性别：" prop="gender">
              <el-select
                v-if="isEdit"
                v-model="form.gender"
                placeholder="请选择"
              >
                <el-option
                  v-for="item in genderSelectList"
                  :key="item.val"
                  :label="item.label"
                  :value="item.val"
                >
                </el-option>
              </el-select>
              <span v-else :class="{ color_gray: !form.gender }">
                {{ $filters.sexFilter(form.gender) }}
              </span>
            </el-form-item>

            <el-form-item label="邮箱：" prop="email">
              <el-input v-if="isEdit" v-model="form.email"></el-input>
              <span v-else :class="{ color_gray: !form.email }">
                {{ form.email || "未填写" }}
              </span>
            </el-form-item>

            <el-form-item label="手机号：" prop="phone">
              <el-input v-if="isEdit" v-model="form.phone"></el-input>
              <span v-else :class="{ color_gray: !form.phone }">
                {{ form.phone || "未填写" }}
              </span>
            </el-form-item>

            <el-form-item label="个人简介：" prop="description">
              <el-input
                v-if="isEdit"
                type="textarea"
                rows="4"
                v-model="form.description"
              ></el-input>
              <span v-else :class="{ color_gray: !form.description }">
                {{ form.description || "未填写" }}
              </span>
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>
    </el-row>

    <el-dialog title="裁剪图片" v-model="dialogVisible" width="600px">
      <vue-cropper
        ref="cropper"
        :src="imgSrc"
        :ready="cropImage"
        :zoom="cropImage"
        :cropmove="cropImage"
        style="width: 100%; height: 400px"
      ></vue-cropper>

      <template #footer>
        <span class="dialog-footer">
          <el-button class="crop-demo-btn" type="primary"
            >选择图片
            <input
              class="crop-input"
              type="file"
              name="image"
              accept="image/*"
              @change="setImage"
            />
          </el-button>
          <el-button type="primary" @click="saveAvatar">上传并保存</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import {
  reactive,
  ref,
  computed,
  watch,
  getCurrentInstance,
  onActivated,
} from "vue";
import { ElMessage } from "element-plus";
import VueCropper from "vue-cropperjs";
import "cropperjs/dist/cropper.css";
import avatar from "../assets/img/img.jpg";
import { useStore } from "vuex";
import { useRoute } from "vue-router";

const initFormData = () => {
  return {
    nickname: null,
    truename: null,
    description: null,
    avatar: null,
    phone: null,
    email: null,
    gender: null,
    departmentId: null,
    groupId: null,
  };
};

export default {
  name: "user",
  components: {
    VueCropper,
  },
  setup() {
    const { proxy } = getCurrentInstance();
    const $api = proxy.$api;
    const $route = useRoute();
    // debugger
    const store = useStore();
    const formRef = ref(null);
    const form = reactive(initFormData());
    // 表单校验规则
    const rules = reactive({
      nickname: [
        {
          required: true,
          trigger: "blur",
          validator: (rule, value, callback) => {
            if (!value) {
              callback(new Error("请输入你的昵称"));
            } else {
              callback();
            }
          },
        },
      ],
    });
    const genderSelectList = reactive([
      { label: "男", val: "1" },
      { label: "女", val: "0" },
    ]);

    const userInfo = computed(() => store.state.user.userInfo);
    // watch()可以直接观察一个包装对象：
    watch(
      () => userInfo,
      (val) => {
        // console.log('watch => userInfo', val.value)
        Object.keys(form).forEach((key) => {
          form[key] = val.value[key];
        });
      },
      { deep: true, immediate: true }
    );

    // 用户头像相关 start ----------------------------------------------------
    const avatarImg = ref(avatar);
    const imgSrc = ref("");
    const cropImg = ref("");
    const dialogVisible = ref(false);
    const cropper = ref(null);

    const showDialog = () => {
      dialogVisible.value = true;
      imgSrc.value = avatarImg.value;
    };

    const setImage = (e) => {
      const file = e.target.files[0];
      if (!file.type.includes("image/")) {
        return;
      }
      const reader = new FileReader();
      reader.onload = (event) => {
        dialogVisible.value = true;
        imgSrc.value = event.target.result;
        cropper.value && cropper.value.replace(event.target.result);
      };
      reader.readAsDataURL(file);
    };

    const cropImage = () => {
      cropImg.value = cropper.value.getCroppedCanvas().toDataURL();
    };

    const saveAvatar = () => {
      avatarImg.value = cropImg.value;
      dialogVisible.value = false;
    };
    // 用户头像相关 end ----------------------------------------------------

    // 控制是否编辑资料
    const isEdit = ref(false);
    const editBtnLoading = ref(false);

    const toggleEditStatus = () => {
      if (editBtnLoading.value) {
        return;
      }
      // 当点击取消的时候，清空表单校验，还原被修改的数据
      if (isEdit.value) {
        formRef.value.resetFields();
      }
      isEdit.value = !isEdit.value;
    };

    // 提交
    const onSubmit = () => {
      formRef.value.validate((valid) => {
        if (valid) {
          editBtnLoading.value = true;
          $api.users
            .usersUpdate(form)
            .then((res) => {
              console.log("usersUpdate => res", res);
              editBtnLoading.value = false;
              isEdit.value = false;
              ElMessage.success("修改成功！");
              store.commit("user/setUserInfo", res.data);
            })
            .catch((err) => {
              editBtnLoading.value = false;
              console.error("usersUpdate error: ", err);
            });
        }
      });
    };

    const bgYellowControl = reactive({
      nickname: false,
      truename: false,
      description: false,
      avatar: false,
      phone: false,
      email: false,
      gender: false,
      departmentId: false,
      groupId: false,
    });

    onActivated(() => {
      Object.keys(bgYellowControl).forEach((key) => {
        bgYellowControl[key] = false;
      });
      if ($route.params) {
        Object.keys($route.params).forEach((key) => {
          if (
            $route.params &&
            Object.prototype.hasOwnProperty.call(bgYellowControl, key)
          ) {
            bgYellowControl[key] = true;
          }
        });
      }
    });

    return {
      form,
      rules,
      formRef,
      cropper,
      avatarImg,
      imgSrc,
      cropImg,
      showDialog,
      dialogVisible,
      setImage,
      cropImage,
      saveAvatar,
      userInfo,
      isEdit,
      editBtnLoading,
      toggleEditStatus,
      onSubmit,
      genderSelectList,
      bgYellowControl,
    };
  },
};
</script>

<style scoped>
.info {
  text-align: center;
  padding: 35px 0;
}
.info-image {
  position: relative;
  margin: auto;
  width: 100px;
  height: 100px;
  background: #f8f8f8;
  border: 1px solid #eee;
  border-radius: 50px;
  overflow: hidden;
}
.info-image img {
  width: 100%;
  height: 100%;
}
.info-edit {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.info-edit i {
  color: #eee;
  font-size: 25px;
}
.info-image:hover .info-edit {
  opacity: 1;
}
.info-name {
  margin: 15px 0 10px;
  font-size: 24px;
  font-weight: 500;
  color: #262626;
}
.crop-demo-btn {
  position: relative;
}
.crop-input {
  position: absolute;
  width: 100px;
  height: 40px;
  left: 0;
  top: 0;
  opacity: 0;
  cursor: pointer;
}
.button {
  padding: 0;
  min-height: auto;
}
.clearfix {
  line-height: 28px;
}
.bg_yellow {
  border-radius: 4px;
  background-color: rgba(222, 184, 135, 0);
  animation: show_bg 5s linear both;
}

@keyframes show_bg {
  0% {
    background-color: rgba(222, 184, 135, 0);
  }
  16% {
    background-color: rgba(222, 184, 135, 1);
  }
  33% {
    background-color: rgba(222, 184, 135, 0);
  }
  49% {
    background-color: rgba(222, 184, 135, 1);
  }
  65% {
    background-color: rgba(222, 184, 135, 0);
  }
  82% {
    background-color: rgba(222, 184, 135, 1);
  }
  100% {
    background-color: rgba(222, 184, 135, 0);
  }
}
</style>
